package Thread;
// 如果是多个线程进行单例模式的使用呢？？
// 我们会想到一个问题：每个线程都需要进行加锁，明明只是判断一下实例对象是否已经被创建，但是现在就需要，每个线程都需要进行加锁完成；
//因此：我们应该设计一个判断条件在外部就判断一下这个实例的对象是否已经创建；
//如果已经存在的话，就不需要进行加锁；
//如果不存在的话，在进行加锁；
//这样就大大的提高起来了效率了；
class SingleTonLazy2 {
    private volatile static SingleTonLazy2  instance = null;
    static Object locker = new Object();

    public static SingleTonLazy2 getInstance() {
        if (instance == null) {
            synchronized (locker) {
                if (instance == null) {
                    instance = new SingleTonLazy2();
                }
            }
        }
        return instance;
    }
}
public class Demo28_3 {
    public static void main(String[] args) throws InterruptedException {
        Object nm1 = new Object();
        Thread t1 = new Thread(() -> {
            SingleTonLazy2.getInstance();
        });
        Thread t2 = new Thread(() -> {
            SingleTonLazy2.getInstance();
        });
        Thread.sleep(5000);
        System.out.println(SingleTonLazy2.getInstance()==SingleTonLazy2.getInstance());
    }
}
//但是在这里也可能会出现一些“内存可见性”的问题，
// （万一多个线程进行执行程序的时候，进行实例化的操作进行的相当慢；
// 就会导致前面学到过得直接获取CPU寄存器或缓存的情况，
// 就无法获取的实例化对象的情况；）
//进而导致“内存可见性”的问题出现；
//同时也出现一些指令重排序的问题，这样也会导致我们对象的实例化难以完成；
//这些都是一些关于在多线程懒汉式的情况下出现的一些实例化对象创建无法成功完成的一些问题；
// 解决办法：非常简单，只需要我们进行设置一个前边学到过的关键字就可以解决上述两个问题；
//即:使用volatile修饰变量instance即可;
